---
--- 获取注册中心应用信息
--- Created by E.T.
--- DateTime: 2018/10/25 11:35
---
local httpTools = require "kong.plugins.gray.tools.http_tools"
local config = require"kong.plugins.gray.tools.config"
local string_tools = require"kong.plugins.gray.tools.string_tools"
local cjson = require"cjson"
local log = kong.log

local _M = {}
local opts ={
    ttl = config.apps_data_ttl,
    resurrect_ttl = 2,
    neg_ttl = 2
}
local re_load = 1
local conf

--随机获取eureka地址
function get_eureka_url()
    math.randomseed(tostring(socket.gettime()):reverse():sub(1, 6))
    local http = string_tools.split(conf.eureka_urls,",")
    local index = math.random(1,#http)
    return http[index]
end

function get_apps()
    if re_load == 50 then
        return nil
    end
    body, code = httpTools.web_get(get_eureka_url())
    if code ~= 200 then
        re_load = re_load+1
        log.notice("请求注册中心失败：",code)
        get_apps(get_eureka_url())
    end
    return body,code
end

--去注册中心拉取所有应用信息
local function load_app_info(api_key)
    --local apikeys, err = kong.dao.eureka_apps:find_all() -- 数据库获取（暂时不用）
    local retTable = {}    --最终产生json的表
    local namesTable = {}    --存放names
    re_load = 1
    log.notice("--------------------------获取注册中心应用------------------------")
    --拉取注册中心应用
    body, code = get_apps()
    local data = cjson.decode(body);
    local apps = data.applications
    for ik, ia in pairs(apps.application) do
        --print("------------------完美分割线--------------------")
        --print("name:", ia.name)
        local normal_index = 1
        local gray_index = 1
        local typeTable = {}   --存放类型应用
        local normalTable = {}   --存放正常应用
        local grayTable = {}   --存放灰度应用
        namesTable[ia.name] = ia.name
        for ak, av in pairs(ia.instance) do
            if av.status == "UP" and av.metadata.instance_status ~= "disable" then
                if av.metadata.instance_status == nil or av.metadata.instance_status == "normal" then
                    normalTable[normal_index] = {}
                    normalTable[normal_index]["ipAddr"] = av.ipAddr
                    normalTable[normal_index]["port"] = av.port["$"]
                    --normalTable[normal_index]["instanceStatus"] = av.metadata.instance_status
                    --print("ipAddr:", av.ipAddr)
                    --print("port:", av.port["$"])
                    normal_index = normal_index + 1
                else
                    grayTable[gray_index] = {}
                    grayTable[gray_index]["ipAddr"] = av.ipAddr
                    grayTable[gray_index]["port"] = av.port["$"]
                    --grayTable[gray_index]["instanceStatus"] = av.metadata.instance_status
                    --print("ipAddr:", av.ipAddr)
                    --print("port:", av.port["$"])
                    gray_index = gray_index + 1
                end
            end
        end
        typeTable["normal"] = normalTable
        typeTable["gray"] = grayTable
        namesTable[ia.name] = typeTable
    end
    local jsonStr = cjson.encode(namesTable);
    log.notice("缓存注册中心应用信息：", jsonStr);
    return cjson.decode(jsonStr)
end
--初始化
local function init(conf)
    local cache_key = kong.dao.eureka_apps:cache_key(config.apps_data_key)
    local value, err = kong.cache:get(cache_key, opts, load_app_info, config.apps_data_key)
    if err then
        log.err("获取缓存错误：", err)
        return nil, { status = 500, message = "没有缓存" }
    end
    --获取缓存值（检查是否缓存成功）
    --for tk, tv in pairs(value) do
    --    log.notice("app->", tk, tv)
    --end
    return value
end

function _M.execute(conf)
    local value, err = init(conf)
end
--获所有应用缓存
function _M.get_eureka_apps(c)
    conf = c
    return init()
end
--获单个应用缓存
function _M.get_eureka_app(key)
    local cache_key = kong.dao.eureka_apps:cache_key(key)
    local value, err = kong.cache:get(cache_key, nil, nil, key)
    if err then
        log.err("获取单个缓存错误：", err)
        return nil, { status = 500, message = key+"没有缓存" }
    end
    return value
end
function _M.clean_cache()
    local cache_key = kong.dao.eureka_apps:cache_key(config.apps_data_key)
    kong.cache:invalidate(cache_key)
end


return _M
